/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define Debug 0
#define Buff_Size 100
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
typedef void(*rb_callback)(i_ringbuffer*);
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
RTC_HandleTypeDef hrtc;

UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;

/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for blinkTask */
osThreadId_t blinkTaskHandle;
const osThreadAttr_t blinkTask_attributes = {
  .name = "blinkTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for rxTaskUart2 */
osThreadId_t rxTaskUart2Handle;
const osThreadAttr_t rxTaskUart2_attributes = {
  .name = "rxTaskUart2",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for writeCardTask */
osThreadId_t writeCardTaskHandle;
const osThreadAttr_t writeCardTask_attributes = {
  .name = "writeCardTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for rxCountingSemUart2 */
osSemaphoreId_t rxCountingSemUart2Handle;
const osSemaphoreAttr_t rxCountingSemUart2_attributes = {
  .name = "rxCountingSemUart2"
};
/* Definitions for rbCountingSem */
osSemaphoreId_t rbCountingSemHandle;
const osSemaphoreAttr_t rbCountingSem_attributes = {
  .name = "rbCountingSem"
};
/* Definitions for hasDataCountingSem */
osSemaphoreId_t hasDataCountingSemHandle;
const osSemaphoreAttr_t hasDataCountingSem_attributes = {
  .name = "hasDataCountingSem"
};
/* Definitions for writeCardCountingSem */
osSemaphoreId_t writeCardCountingSemHandle;
const osSemaphoreAttr_t writeCardCountingSem_attributes = {
  .name = "writeCardCountingSem"
};
/* USER CODE BEGIN PV */
int n;
uint8_t tx_buff[Buff_Size] = "hell0,uart DMArn";
uint8_t rx_buff[Buff_Size] = "";

int rx_buff_size;

uint8_t packet_buff[Buff_Size];

i_ringbuffer rb;

uint8_t writeCounter = 0;

#define RBLEN 128
uint8_t rb_data[RBLEN];

uint8_t write_proc_state = 0;
uint8_t write_block = 0;

// 记录时间
uint32_t workTime;
uint32_t writeBeginTime;
uint32_t writeCost;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_RTC_Init(void);
static void MX_USART2_UART_Init(void);
void StartDefaultTask(void *argument);
void StartTaskBlink(void *argument);
void StartTaskUart2Rx(void *argument);
void StartTaskWriteCard(void *argument);

/* USER CODE BEGIN PFP */
void OnRtcWakeup();
int SafeRingBuffer(i_ringbuffer* handle, int forceLock, rb_callback callback);
void OnRx();
void OnTx(uint8_t *data, uint32_t len);

void SaveBuffer(i_ringbuffer* handle);

void on_tag(uint8_t* uid);
void on_tag_block(uint8_t blockNum, uint8_t* data, uint8_t errCode);
void on_tag_write_block(uint8_t blockNum, uint8_t errCode);
void on_tag_write_blocks(uint8_t blockNum, uint8_t blocks, uint8_t errCode);

void write_card_proc();

int __io_putchar(int ch) {
	ITM_SendChar(ch);
	return ch;
}

void OnRtcWakeup() {
	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;
	if(HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN)==HAL_OK)
	{
		HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
		//printf("%d.%d.%d %d:%d:%d \r\n",sDate.Year+2000,sDate.Month,sDate.Date,sTime.Hours,sTime.Minutes,sTime.Seconds);
		workTime = sTime.Minutes*60+sTime.Seconds;
	}
}

void OnTx(uint8_t *data, uint32_t len) {
	HAL_UART_Transmit_DMA(&huart2, data, len);
	while(!__HAL_UART_GET_FLAG(&huart2,UART_FLAG_TC));
}

void on_tag_write_block(uint8_t blockNum, uint8_t errCode) {
	printf("<<write block %d[err_code:%d]\t", blockNum, errCode);
	if (errCode == 0) {
		printf("success");
	} else {
		printf("fail");
	}
	printf("\n");
	if (errCode != 0x00) {
		return;
	}

	write_card_proc();
}

void on_tag_write_blocks(uint8_t blockNum, uint8_t blocks, uint8_t errCode) {
	printf("<<write blocks %d-%d[err_code:%d]\t", blockNum, blocks, errCode);
	if (errCode == 0) {
		printf("success");
	} else {
		printf("fail");
	}
	printf("\n");
	if (errCode != 0x00) {
		return;
	}

	write_card_proc();
}

void write_card_proc() {

	uint8_t stateChange = 0;
	int i;

	switch(write_proc_state) {
	case 0x00: //
		write_block = 0x00; // from block[02]
		write_proc_state++;

		stateChange = 1;
		writeCounter++;
		writeCounter%=250;
		printf(">>write card from block [%d] total 28 blocks.\n", write_block);
		break;

	case 0x01: // block[0-1]
		if (write_block > 1) {
			write_proc_state++;
			stateChange = 1;
			break;
		}
		//printf("write block %d\n", write_block);

		printf(">>write blocks from %d(%d blocks)[with:%02x]\n", write_block, 2, writeCounter);
		for (i = 0; i < 2*4; i++) {
			tx_buff[i] = writeCounter;
		}
		Ck156_Write_Blocks(write_block, 2, tx_buff, on_tag_write_blocks);
		write_block+=2;
		break;
	case 0x02: // block[2-13]
		if (write_block > 13) {
			write_proc_state++;
			stateChange = 1;
			break;
		}
		//printf("write block %d\n", write_block);

		printf(">>write blocks from %d(%d blocks)[with:%02x]\n", write_block, 12, writeCounter);
		for (i = 0; i < 12*4; i++) {
			tx_buff[i] = writeCounter;
		}
		Ck156_Write_Blocks(write_block, 12, tx_buff, on_tag_write_blocks);
		write_block+=12;
		break;
	case 0x03: // block[14-27]
		if (write_block > 27) {
			write_proc_state++;
			stateChange = 1;
			break;
		}
		//printf("write block %d\n", write_block);

		printf(">>write blocks from %d(%d blocks)[with:%02x]\n", write_block, 14, writeCounter);
		for (i = 0; i < 14*4; i++) {
			tx_buff[i] = writeCounter;
		}
		Ck156_Write_Blocks(write_block, 14, tx_buff, on_tag_write_blocks);
		write_block+=14;
		break;

	case 0x04:
		printf(">>write proc complete.\n");
		writeCost = workTime - writeBeginTime;
		printf("++write card process cost: %ld[%ld-%ld]\n", writeCost, workTime, writeBeginTime);
		write_proc_state++;
		break;
	default:
		return;
	}
	if (stateChange != 0x00) { // 状态改变
		write_card_proc();
	}

}

void on_tag_block(uint8_t blockNum, uint8_t* data, uint8_t errCode) {
	int i;
	printf("<<read block %d[%d]\n", blockNum, errCode);
	if (errCode == 0) {
		printf("block:<");
		for (i=0; i<4; i++) {
			printf("%02x ", data[i]);
		}
		printf(">\n");
	}
	writeBeginTime = workTime;
	printf("++write card process start with: %ld\n", writeBeginTime);

	write_proc_state = 0;
	write_card_proc();
}

void on_tag(uint8_t* uid) {
	int i;
	printf("UID:<");
	for (i=0; i<8; i++) {
		printf("%02x ", uid[i]);
	}
	printf(">\n");

	// TODO 准备数据
	Ck156_Read_Block(2, on_tag_block); // 试验性读block2
}

void OnRx() {

	__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除标志
    HAL_UART_DMAStop(&huart2); //关闭DMA

	///////////////////////////////////////////////
    rx_buff_size = Buff_Size - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
    SafeRingBuffer(&rb, 1, SaveBuffer);
    osSemaphoreRelease(rxCountingSemUart2Handle);
	//////////////////////////////////////////////

	HAL_UART_Receive_DMA(&huart2,rx_buff,Buff_Size);//重新打开DMA接收
}

void SaveBuffer(i_ringbuffer* handle) {
	int i;
	if (Debug == 1) {
		printf("receive data size: %d\n", rx_buff_size);
		for (i=0; i<rx_buff_size; i++) {
			printf("%02x ", rx_buff[i]);
		}
		printf("\n");
	}

	// rx --> buffer
	if (Debug == 1) {
		printf("rx-->ring_buffer: %d\n", rx_buff_size);
	}
	if (I_Ring_Buffer_WriteBytes(&rb, rx_buff, rx_buff_size) != I_RING_BUFFER_SUCCESS) {
		if (Debug == 1) {
			printf("ring buffer write fail\n");
		}
		return;
	}
	if (Debug == 1) {
		I_Ring_Status(&rb);
	}
}

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_RTC_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */

//  HAL_UART_Transmit(&huart2, tx_buff, sizeof(tx_buff), 200);
//  HAL_Delay(500);
  printf("print application welcome msg\n");
//  HAL_UART_Transmit_DMA(&huart2, tx_buff, sizeof(tx_buff));
//  while(!__HAL_UART_GET_FLAG(&huart2,UART_FLAG_TC));
  printf("application welcome process OK.\n");
  if (I_Ring_Buffer_Init(&rb, rb_data, RBLEN)) {
	  printf("create ring buffer success\n");
  } else {
	  printf("create ring buffer failed\n");
	  Error_Handler();
  }
  SetTagListener(on_tag);
  /* USER CODE END 2 */

  /* Init scheduler */
  osKernelInitialize();

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* Create the semaphores(s) */
  /* creation of rxCountingSemUart2 */
  rxCountingSemUart2Handle = osSemaphoreNew(2, 0, &rxCountingSemUart2_attributes);

  /* creation of rbCountingSem */
  rbCountingSemHandle = osSemaphoreNew(2, 0, &rbCountingSem_attributes);

  /* creation of hasDataCountingSem */
  hasDataCountingSemHandle = osSemaphoreNew(2, 0, &hasDataCountingSem_attributes);

  /* creation of writeCardCountingSem */
  writeCardCountingSemHandle = osSemaphoreNew(2, 0, &writeCardCountingSem_attributes);

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* creation of blinkTask */
  blinkTaskHandle = osThreadNew(StartTaskBlink, NULL, &blinkTask_attributes);

  /* creation of rxTaskUart2 */
  rxTaskUart2Handle = osThreadNew(StartTaskUart2Rx, NULL, &rxTaskUart2_attributes);

  /* creation of writeCardTask */
  writeCardTaskHandle = osThreadNew(StartTaskWriteCard, NULL, &writeCardTask_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  osSemaphoreRelease(rbCountingSemHandle);
  /* USER CODE END RTOS_EVENTS */

  /* Start scheduler */
  osKernelStart();

  /* We should never get here as control is now taken by the scheduler */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief RTC Initialization Function
  * @param None
  * @retval None
  */
static void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */

  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */

  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }

  /** Enable the WakeUp
  */
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */

  /* USER CODE END RTC_Init 2 */

}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
  HAL_UART_Receive_DMA(&huart2,rx_buff,Buff_Size);
  /* USER CODE END USART2_Init 2 */

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel6_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
  /* DMA1_Channel7_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LDE_GPIO_Port, LDE_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : LDE_Pin */
  GPIO_InitStruct.Pin = LDE_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LDE_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

int SafeRingBuffer(i_ringbuffer* handle, int forceLock, rb_callback callback) {
	osStatus_t status;
	for (;;) {
		status = osSemaphoreAcquire(rbCountingSemHandle, 0);
		if (status == osOK) {
			break;
		}
		if (forceLock == 0) {
			return 0;
		}
	}
	callback(handle);
	osSemaphoreRelease(rbCountingSemHandle);
	return 1;
}
/* USER CODE END 4 */

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(20000);
    printf("status report\n");
  }
  /* USER CODE END 5 */
}

/* USER CODE BEGIN Header_StartTaskBlink */
/**
* @brief Function implementing the blinkTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskBlink */
void StartTaskBlink(void *argument)
{
  /* USER CODE BEGIN StartTaskBlink */
  /* Infinite loop */
  for(;;)
  {
    osDelay(6000000);
    n++;
    n%=1000;
    printf("blink task %d.\n", n);
    HAL_GPIO_TogglePin(LDE_GPIO_Port, LDE_Pin);
  }
  /* USER CODE END StartTaskBlink */
}

/* USER CODE BEGIN Header_StartTaskUart2Rx */
/**
* @brief Function implementing the rxTaskUart2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskUart2Rx */
void StartTaskUart2Rx(void *argument)
{
  /* USER CODE BEGIN StartTaskUart2Rx */
  osStatus_t status;
  /* Infinite loop */
  for(;;)
  {
    osDelay(50);
    status = osSemaphoreAcquire(rxCountingSemUart2Handle, 0);
    if (status == osOK) {
    	if (Debug == 1) {
    		printf("handle packet task start\n");
    	}
    	//SafeRingBuffer(&rb, 1, packetHandle);
    	OnNewData(&rb);
    	if (Debug == 1) {
    		I_Ring_Status(&rb);
    		printf("handle packet task end\n");
		}
    }
  }
  /* USER CODE END StartTaskUart2Rx */
}

/* USER CODE BEGIN Header_StartTaskWriteCard */
/**
* @brief Function implementing the writeCardTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskWriteCard */
void StartTaskWriteCard(void *argument)
{
  /* USER CODE BEGIN StartTaskWriteCard */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000000);

    //Ck156_Read_Block(2, on_tag_block);
  }
  /* USER CODE END StartTaskWriteCard */
}

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM2 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM2) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  printf("error handler");
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
